The interface-segregation principle is one of the five SOLID principles of Object-Oriented Design.[1] The ISP is similar to the High Cohesion Principle of GRASP.[2] It is a software development principle used for clean development and is intended to help developers avoid making their software impossible to change. If followed, the ISP will help a system stay decoupled and thus easier to refactor, change, and redeploy. The ISP says that once an interface has become too 'fat' it needs to be split into smaller and more specific interfaces so that any clients of the interface will only know about the methods that pertain to them. In a nutshell, no client should be forced to depend on methods it does not use.[1]
Martin Fowler's name for smaller interfaces which only include the needed methods is 'Role Interface'. [3]
Contents |
Within OOD, interfaces provide layers of abstraction. This abstraction facilitates conceptual explanation of the code and creates a barrier preventing dependencies (as described by The Dependency Inversion Principle).
According to the many software experts who have signed the Manifesto for Software Craftsmanship, writing well crafted and explanatory software is almost as important as writing working software.[4] Using interfaces to further describe the intent of the software is often a good idea.
It is also true that a system may become so coupled, where each class is dependent on other classes that depend on other classes, that it is no longer possible to make a change in one place without having a ripple effect and having to make subsequent changes in many places.[1] This is why using an interface or an abstract class can be valuable in any object-oriented software project.
The ISP was first used and formulated by Robert C. Martin when he was doing some consulting for Xerox. Xerox had created a new printer system which could perform a variety of tasks such as stapling a set of printed papers, faxing, and so forth. The software for this system was created from the ground up and performed its tasks successfully, but as the software grew it became harder and harder to change. Each time a change, even the smallest of changes, was made it could take nearly an hour to recompile and redeploy. This was making it near impossible to continue development, so they hired Martin to help them out.
The issue with their code was that there was one main Job class that was used by almost all of the tasks. Anytime a print job or a stapling job had to be done, a call was made to some method in the Job class. This meant that the Job class was getting huge or 'fat', with multitudes of different methods which were specific to a variety of different clients. This meant that a staple job would know about all the methods of the print job, even though the staple class had no use for them. The clients were being forced to depend on methods they did not use. When a developer had to change a small detail about a print job, every one of the classes that used the Job class would have to be recompiled.
The solution suggested by Robert has now become the Interface Segregation Principle. He suggested that they add a layer of interfaces between the Job class and all of its clients. Using the properties of the Dependency Inversion Principle, all of the dependencies could be reversed. Instead of having just one 'fat' Job class that all the tasks used, there would be a Staple Job interface or a Print Job interface that would be used by the Staple class or Print class, respectively, and would call methods of the Job class. Therefore there was an interface created for each job, and the Job class would implement all of these interfaces. This segregation of interfaces vastly decoupled the software allowing the clients like the Staple class to only depend on the methods it cared about. Thus if a developer made a change to the Print Job, the Staple Job would be unaffected and have no need to recompile.
The Xerox example is a clear violation of the Interface Segregation Principle, but not all violations are so clear cut. A more commonly known example is the ATM Transaction example given in Agile Software Development: Principles, Patterns, and Practices [1] and in an article also written by Robert C. Martin specifically about the ISP.[5] This example is about an interface for the User Interface for an ATM, that handles all requests such as a deposit request, or a withdrawal request, and how this interface needs to be segregated into individual and more specific interfaces.